home *** CD-ROM | disk | FTP | other *** search
/ The Programmer Disk / The Programmer Disk (Microforum).iso / xpro / pascal / pro2 / 3dgraph.pas < prev    next >
Pascal/Delphi Source File  |  1986-12-02  |  43KB  |  1,325 lines

  1. program graph2 ;  (*    4/5/86  Joe Martin 862-7108  *)
  2.  
  3. {$D-}
  4. {$V-}
  5. Label Finish , Cross , start ;
  6.  
  7. CONST
  8.    MaxX : integer = 640 ; MaxY : integer=400 ;
  9.    THETA : REAL=0.3 ; PHI : REAL=1.2 ;    OBJECT: Real=50   ;
  10.       LowX : REAL=-10 ; HighX : REAL=10 ;       IMAGE: Real=750  ;
  11.       LowY : REAL=-10; HighY : REAL=10 ; XIncrement : REAL=0.5 ;
  12.     CenterX: Real=200 ; CenterY: Real=100 ; YIncrement : real=0.5 ;
  13.     ScaleX : Real=2 ; ScaleY : Real=1 ;
  14.    space='                                                                           ' ;
  15.    F1 = #59 ;
  16. Type
  17.     NodeType = (binop,unop,number) ;
  18.     Node     = ^NodeRec ;
  19.     NodeRec  = Record
  20.                      Case Tag : NodeType of
  21.                       binop : (operator : Char ;
  22.                                LeftOperand,
  23.                                RightOperand : Node) ;
  24.                       unop  : (Uoperator : Char ;
  25.                                Operand   : Node) ;
  26.                     Number  : (Num : Real) ;
  27.                      End ; {  case  }
  28.     Pair = record
  29.                  x : integer ;
  30.                  y : integer ;
  31.            end ;
  32.     PBytePointer = ^P_Byte ;
  33.     P_Byte = array[1..400,0..79] of byte ;
  34.  
  35.     PairPointer  = ^Pt ;
  36.     SPairPointer = ^SPt ;
  37.     Pt  = array[1..90,1..152] of pair ;
  38.     SPt = array[1..90,1..152] of pair ;
  39.  
  40.     EvenVideo = array[0..99,0..79] of byte ;
  41.     OddVideo  = array[0..99,0..79] of byte ;
  42.  
  43.     anystring = string[80] ;
  44.     str80     = string[80] ;
  45.     str20     = string[20] ;
  46.     CharSet   = set of char ;
  47. var
  48.    N : node ;
  49.    i , p1 , p2 , K , Position ,
  50.    TM , XCoor , YCoor , NumPoints , NumCurves , AltX , AltY : INTEGER;
  51.  
  52.    ScCvPt    : SPairPointer ;
  53.    CvPt      : PairPointer ;
  54.    PrintByte : PBytePointer ;
  55.  
  56.     UpY     : array[1..640] of integer ;
  57.     LoY     : array[1..640] of integer ;
  58.     UpSY    : array[1..640] of integer ;
  59.     LoSY    : array[1..640] of integer ;
  60.     Hide , First : Boolean ;
  61.  
  62.    EV : EvenVideo absolute $B800:0000 ;
  63.    OV : OddVideo  absolute $BA00:0000 ;
  64.  
  65.    DrawLine , DIncr , PLine , CLine , C , C1 , P : integer ;
  66.    CTCP , STCP ,
  67.    SPCT , SPST ,
  68.    SinTheta,SinPhi,CosTheta,CosPhi, Im1 , Im2 , Z , Z1, Z2 ,
  69.    Z3 ,X , Y , Ax , Ay ,
  70.    Zero , Ptime : REAL ;
  71.    Screen , Form , Hidden , LowOrHigh : Boolean ;
  72.    ch,E : char ;
  73.    Equation: string[75] ;
  74.    time1 , time2 : real ;
  75.    a , b , d : integer ;
  76.  
  77. Procedure Tone ;
  78.    begin
  79.      sound(440) ;
  80.      delay(250) ;
  81.      nosound ;
  82.    end ;
  83.  
  84. {----------------------------- Time ------------------------------------}
  85.  
  86. function timer : real ; { *** PTime of type real must be global *** }
  87.  
  88. type
  89.   regpack = record
  90.               ax,bx,cx,dx,bp,si,di,ds,es,flags: integer;
  91.             end;
  92.  
  93. var
  94.   recpack:          regpack;             {assign record}
  95.   ah,al,ch,cl,dh:   byte;
  96.   hour,min,sec:     integer ;
  97.  
  98. begin
  99.   ah := $2c;                             {initialize correct registers}
  100.   with recpack do
  101.   begin
  102.     ax := ah shl 8 + al;
  103.   end;
  104.   intr($21,recpack);                     {call interrupt}
  105.   with recpack do
  106.   begin
  107.     hour := cx shr 8 ;
  108.     min  := cx mod 256 ;
  109.     sec  := dx shr 8 ;
  110.   end;
  111.   timer := ((min * 60) + sec) - PTime ;
  112. end;
  113.  
  114. {------------------ Evaluate formula : Parser Routine -----------------------}
  115.  
  116. Function BinopNode(opr:char ; lopr , ropr : node) : node ;
  117.     Var n : node ;
  118.     begin
  119.          if (lopr=nil) or (ropr=nil) then BinopNode := Nil
  120.          else begin
  121.               New(n) ;
  122.               with n^ do begin
  123.                    tag := binop ;
  124.                    Operator := opr ;
  125.                    LeftOperand := lopr ;
  126.                    RightOperand := ropr ;
  127.                          end ;
  128.               binopnode := n ;
  129.               end ;
  130.     end ;
  131.  
  132. Function UnopNode(opr : char ; Opand : node) : node ;
  133.     Var N : node;
  134.     begin
  135.                    New(n) ;
  136.                    with N^ do begin
  137.                    tag := unop ;
  138.                    Uoperator := opr ;
  139.                    Operand := Opand ;
  140.                               end ;
  141.               UnopNode := n ;
  142.     end ;
  143.  
  144. Function NumberNode(I : real) : node ;
  145.     Var N : node ;
  146.     begin
  147.          New(N) ;
  148.          with n^ do begin
  149.               Tag := Number ;
  150.               Num := I ;
  151.                     end ;
  152.          NumberNode := N ;
  153.     end ;
  154.  
  155. {**************************************************************************}
  156. procedure Parse(var IsFormula: Boolean; { True if formula}
  157.                    var Formula: AnyString; { Fomula to evaluate}
  158.                    var Value: Node;  { Pointer to first record }
  159.                    var ErrPos: Integer);{ Position of error }
  160. const
  161.   Numbers: set of Char = ['0'..'9'];
  162.   EofLine  = ^M;
  163.  
  164. var
  165.   Pos: Integer;    { Current position in formula                     }
  166.   Ch: Char;        { Current character being scanned                 }
  167.   EXY: string[3];  { Intermidiate string for conversion              }
  168.   N : Node ;
  169.  
  170. { Procedure NextCh returns the next character in the formula         }
  171. { The variable Pos contains the position ann Ch the character        }
  172.  
  173.   procedure NextCh;
  174.   begin
  175.     repeat
  176.       Pos:=Pos+1;
  177.       if Pos<=Length(Formula) then
  178.       Ch:=Formula[Pos] else Ch:=eofline;
  179.     until Ch<>' ';
  180.   end  { NextCh };
  181.  
  182. Procedure PrevCh ;
  183.     begin
  184.     repeat
  185.       if pos>1 then begin
  186.       Pos:=Pos-1;
  187.       Ch:=Formula[Pos]   end ;
  188.     until Ch<>' ';
  189.   end ;
  190.  
  191.   function Expression: Node;
  192.   var
  193.     N : Node ;
  194.     E: Real;
  195.     Opr: Char;
  196.  
  197.       function Term: Node;
  198.       var
  199.         N : Node ;
  200.         T: Real;
  201.  
  202.           function Factor: Node;
  203.           type
  204.               StandardFunction=(fabs,fsqrt,fsqr,fsin,fcos,farctan,fln,flog,
  205.                                 fexp,ffact) ;
  206.                                 StandardFunctionList = array[standardFunction] of
  207.                                                             string[6] ;
  208.           Const
  209.                StandardFunctionNames: StandardFunctionList=('ABS','SQRT',
  210.                                       'SQR','SIN','COS','ARCTAN','LN',
  211.                                       'LOG','EXP','FACT');
  212.  
  213.           var
  214.             Found : boolean ;
  215.             F: Real;
  216.             Start , L : integer ;
  217.             Sf : StandardFunction ;
  218.  
  219.           begin { Function Factor }
  220.             NextCh ;
  221.             if Ch in Numbers then
  222.             begin
  223.               Start:=Pos;
  224.               repeat NextCh until not (Ch in Numbers);
  225.               if Ch='.' then repeat NextCh until not (Ch in Numbers);
  226.               if Ch='E' then
  227.               begin
  228.                 NextCh;
  229.                 repeat NextCh until not (Ch in Numbers);
  230.               end;
  231.               Val(Copy(Formula,Start,Pos-Start),F,ErrPos);
  232.               Factor := NumberNode(F) ;
  233.               PrevCh ;
  234.             end
  235.  
  236.             else if Ch = '-' then Factor:=UnopNode(Ch,Factor)
  237.             else if Ch = '(' then begin
  238.                     Factor:=Expression ;
  239.                     nextCh ;
  240.                     if Ch <> ')' then writeln('close parenthesis expected') ;
  241.                                   end
  242.  
  243.             else if ch in ['X','Y'] then
  244.                  begin
  245.                       Opr:=ch ;
  246.                       Factor := UnopNode(Opr,nil) ;
  247.                  end
  248.             else Begin
  249.                  found:= false ;
  250.                  for sf := Fabs to ffact do
  251.                  if Not found then
  252.                  begin
  253.                       l := length(StandardFunctionNames[sf]) ;
  254.                       if copy(Formula,pos,l)=STandardFunctionNames[sf] then
  255.                       begin
  256.                         Pos := Pos + l - 1 ; nextCh ;
  257.                         N := Expression ; NextCh ;
  258.                         Case sf of
  259.                           fabs     : Factor:=UnopNode('a',N) ;
  260.                           fsqrt    : Factor:=UnopNode('b',N) ;
  261.                           fsqr     : Factor:=UnopNode('c',N) ;
  262.                           fsin     : Factor:=UnopNode('d',N) ;
  263.                           fcos     : Factor:=UnopNode('e',N) ;
  264.                           farctan  : Factor:=UnopNode('f',N) ;
  265.                           fln      : Factor:=UnopNode('g',N) ;
  266.                           flog     : Factor:=UnopNode('h',N) ;
  267.                           fexp     : Factor:=UnopNode('i',N) ;
  268.                           ffact    : Factor:=UnopNode('j',N) ;
  269.                         end ;
  270.                         found := True ;
  271.                       end ;
  272.                   end ;
  273.                   if not found then begin
  274.                       writeln('illegal expression') ;
  275.                       errpos := pos ;
  276.                       Factor := Nil ;
  277.                                     end ;
  278.                 end ;
  279.           end { function Factor};
  280.  
  281.     begin { Term }
  282.       N:=Factor;
  283.       Term := N ;
  284.       if N<>Nil then begin
  285.          NextCh ;
  286.          if (Ch='^') or (Ch='*') or (Ch='/') then   begin
  287.             Term := BinopNode(Ch,N,Term) ;
  288.                                        end
  289.           else PrevCh ;
  290.                      end ;
  291.     end { Term };
  292.  
  293.   begin { Expression }
  294.     N := Term ;
  295.     Expression := N ;
  296.     if N<>Nil then begin
  297.        NextCh ; Opr := Ch ;
  298.        if (Opr='+') or (Opr='-') then begin
  299.           Expression := BinopNode(Opr,N,Expression) ;
  300.                                     end
  301.         else if Ch<>eofline then
  302.             PrevCh ;
  303.                    end ;
  304.   end { Expression };
  305.  
  306. begin { procedure Parser }
  307.   if Formula[1]='.' then Formula:='0'+Formula;
  308.   if Formula[1]='+' then delete(Formula,1,1);
  309.   IsFormula:=false;
  310.   Pos:=0;
  311.   Value := Expression ;
  312.   if Ch=EofLine then ErrPos:=0 else ErrPos:=Pos;
  313. end { Evaluate };
  314.  
  315. {-------------------- Evaluate Parse Tree -----------------------------------}
  316. function Fact(I: Integer): Real;
  317.               begin
  318.                 if I > 0 then begin Fact:=I*Fact(I-1); end
  319.                 else Fact:=1;
  320.               end  { Fact };
  321.  
  322. Function Eval(N:node) : Real ;
  323.     Var op1 , op2 , Re : Real ;
  324.         a : integer ;
  325.     Begin
  326.       With N^ do
  327.        Case tag of
  328.          Binop : begin
  329.                    Op1 := Eval(LeftOperand) ;
  330.                    Op2 := Eval(RightOperand) ;
  331.                    Case Operator of
  332.                      '+' : Eval := Op1 + Op2 ;
  333.                      '-' : Eval := Op1 - Op2 ;
  334.                      '*' : Eval := Op1 * Op2 ;
  335.                      '/' : begin
  336.                              if Op2=0 then Op2 := Zero ;
  337.                              Eval := Op1 / Op2 ;
  338.                            end ;
  339.                      '^' : begin
  340.                              Re := Op1 ;
  341.                              for a := 1 to Trunc(Op2-1) do
  342.                                  Re := Re * Op1 ;
  343.                              Eval := Re ;
  344.                            end ;
  345.                    end ;
  346.                  end ;
  347.  
  348.        Unop  : begin
  349.                    if OPerand<>nil then Op1 := Eval(Operand) ;
  350.                    Case UOperator of
  351.                      '-' : Eval := -Op1 ;
  352.                      'X' : Eval := X ;
  353.                      'Y' : Eval := Y ;
  354.                      'a' : Eval := abs(Op1) ;
  355.                      'b' : Eval := Sqrt(Op1) ;
  356.                      'c' : Eval := Sqr(Op1) ;
  357.                      'd' : Eval := sin(Op1) ;
  358.                      'e' : Eval := Cos(Op1) ;
  359.                      'f' : Eval := arctan(Op1) ;
  360.                      'g' : Eval := Ln(Op1) ;
  361.                      'h' : Eval := ln(Op1)/ln(10) ;
  362.                      'i' : Eval := exp(Op1) ;
  363.                      'j' : Eval := Fact(trunc(Op1)) ;
  364.                    end ;
  365.                  end ;
  366.  
  367.        Number  : Eval := Num ;
  368.  
  369.        end ;
  370.    end ;
  371.  
  372. {---------------------------------------------------------------------------}
  373. {------------------------- Input Routine -----------------------------------}
  374.  
  375. Procedure Beep ;
  376.     begin
  377.          sound(440) ;
  378.          delay(50) ;
  379.          NoSound ;
  380.     end ;
  381.  
  382. Procedure Color(F,B : integer) ;
  383.    begin
  384.         TextColor(F) ;
  385.         TextBackGround(B) ;
  386.    end ;
  387.  
  388. Procedure HighColor ;
  389.    begin
  390.         Color(14,4) ;
  391.    end ;
  392. Procedure LowColor ;
  393.    begin
  394.         Color(15,1) ;
  395.    end ;
  396.  
  397. Procedure HighLight(Str1 : char) ;
  398.     Var    x,y : integer ;
  399.     begin
  400.          x := wherex ; y := wherey ;
  401.          highcolor ;
  402.          write(str1);
  403.          lowcolor ;
  404.          gotoxy(x,y) ;
  405.     end ;
  406.  
  407. Procedure Input(Col,Row,Wide:Byte ; TypeSet:Charset ; Stop:Str20 ;
  408.                   Var OutStr:Str80 ; Var Jump:char ) ;
  409.  
  410.    Label Bend ;
  411.    Var  x1,y1,len : integer ;
  412.         OutPut : string[80] ;
  413.         Ch : char ;
  414.  
  415.    begin
  416.         OutPut := OutStr ;  Jump := '*' ;
  417.         y1 := Row ;
  418.         Len := Length(OutPut) ; x1 := Len+1 ;
  419.         gotoxy(col,row) ;
  420.         LowColor ;
  421.         write(copy(OutPut+space,1,wide)) ;
  422.         gotoxy(col+x1-1,row) ;
  423.         highlight('_') ;
  424.  
  425.      Repeat
  426.            read(kbd,Ch) ; len := Length(OutPut) ;
  427.  
  428.            if Ch in TypeSet then begin
  429.                     if (len<wide) and (x1=len+1) then
  430.                        begin
  431.                             Ch := upcase(Ch) ;
  432.                             OutPut := OutPut + Ch ;
  433.                             gotoxy(col,row) ;
  434.                             write(OutPut) ;
  435.                             x1 := x1 + 1 ; Highlight('_') ;
  436.                        end
  437.                        else if (len<wide) and (x1<len+1) then
  438.                              begin
  439.                               Ch := upcase(Ch) ;
  440.                               insert(Ch,OutPut,x1) ;
  441.                               x1 := x1 + 1 ;
  442.                               gotoxy(col,row) ;
  443.                               write(OutPut) ;
  444.                               gotoxy(col+x1-1,Row) ;
  445.                               highlight(output[x1]) ;
  446.                              end ;
  447.                      if len = wide then Beep ;
  448.                                  end
  449.  
  450.            Else if Ch = #08 then begin
  451.                            if Len > 0 then begin
  452.                               x1 := x1 - 1 ;
  453.                               delete(OutPut,x1,1) ;
  454.                               gotoxy(col,row) ;
  455.                               write(output,'  ') ;
  456.                               gotoxy(col+x1-1,Row) ;
  457.                               if x1=len then highlight(' ')
  458.                               else highlight(output[x1]) ;
  459.                                             end ;
  460.                             end
  461.  
  462.            Else if Ch = #27 then begin
  463.                 if keypressed then begin
  464.                    read(kbd,jump) ;
  465.                    case jump of
  466.   (* left arrow *)   'K' : if x1 > 1 then begin
  467.                              x1:=x1-1 ;
  468.                              gotoxy(Col+x1,row) ;
  469.                              if x1+1=Len+1 then write(' ')
  470.                              else write(output[x1+1]);
  471.                              gotoxy(Col+x1-1,row) ; highlight(output[x1]) ;
  472.                                           end ;
  473.   (* right arrow *)  'M' : if x1 < len+1 then begin
  474.                              x1 := x1 +1 ;
  475.                              gotoxy(Col+x1-2,row) ; write(output[x1-1]) ;
  476.                              gotoxy(Col+x1-1,row) ;
  477.                              if x1=len+1 then highlight(' ')
  478.                              else highlight(output[x1]) ;
  479.                                               end ;
  480.  (* Home *)          'G' : begin
  481.                              x1 := 1 ;
  482.                              gotoxy(col,row) ; write(output) ;
  483.                              gotoxy(col,row) ; highlight(output[1]) ;
  484.                            end ;
  485.                       'H' : goto Bend ;
  486.                       'P' : goto Bend ;
  487.                       F1  : begin color(15,0) ; clrscr ; halt ; end ;
  488.                    end ;
  489.                                     end
  490.                       Else begin Jump := '^' ;  goto Bend ; end ;
  491.                                   end
  492.  
  493.            Else if Pos(Ch,Stop)=0 then Beep ;
  494.  
  495.      Until Pos(Ch,Stop) <> 0 ;
  496.  Bend :
  497.         if OutPut <> '' then OutStr := OutPut ;
  498.         color(11,0) ;
  499.         gotoxy(col,row) ;
  500.         write(copy(OutStr+space,1,wide)) ;
  501.    end ;
  502. {-----------------------------------------------------------------------------}
  503. Procedure InputN(Col,Row,W,D:Byte ; Var Num:real ; Var Jump:char ) ;
  504.    Label Bend ;
  505.    Var  x1,y1,len,code : integer ;
  506.         NumStr : string[80] ;
  507.         Ch : char ;
  508.  
  509.    begin
  510.         Str(Num:W:D,NumStr) ;                    { Get Number in NumStr }
  511.         while Pos(' ',NumStr)<>0 do              { Delete all spaces    }
  512.           delete(NumStr,Pos(' ',NumStr),1) ;     { from NumStr          }
  513.         Jump := '*' ;
  514.         NumStr:=copy(NumStr+Space,1,W) ;       { add spaces to left justify }
  515.                                                { NumStr is now full width   }
  516.         x1 := 1 ;                              { x1=1 , Cursor Position }
  517.      repeat
  518.         gotoxy(col,row) ;
  519.         LowColor ;
  520.         write(NumStr) ;
  521.         gotoxy(col,row) ;
  522.         highlight(NumStr[1]) ;
  523.  
  524.      Repeat
  525.            read(kbd,Ch) ; len := Length(NumStr) ;
  526.  
  527.            if Ch in ['0'..'9','-','.',' '] then begin
  528.                             delete(NumStr,x1,1) ;
  529.                             insert(Ch,NumStr,x1) ;
  530.                             gotoxy(col+x1-1,row) ;
  531.                             write(Ch) ;
  532.                             if x1<W then x1 := x1 + 1 ;
  533.                             gotoxy(col+x1-1,row) ;
  534.                             Highlight(NumStr[x1]) ;
  535.                                                 end
  536.  
  537.            Else if Ch = #08 then begin
  538.                            if x1 > 1 then begin
  539.                               x1 := x1 - 1 ;
  540.                               delete(NumStr,x1,1) ;
  541.                               NumStr := NumStr+' ' ;
  542.                               gotoxy(col,row) ;
  543.                               write(NumStr) ;
  544.                               gotoxy(col+x1-1,Row) ;
  545.                               highlight(NumStr[x1]) ;
  546.                                             end ;
  547.                             end
  548.  
  549.            Else if Ch = #27 then begin
  550.                 if keypressed then begin
  551.                    read(kbd,jump) ;
  552.                    case jump of
  553.   (* left arrow *)   'K' : if x1 > 1 then begin
  554.                              x1:=x1-1 ;
  555.                              gotoxy(col,row) ; write(NumStr) ;
  556.                              gotoxy(Col+x1-1,row) ;
  557.                              highlight(NumStr[x1]) ;
  558.                                           end ;
  559.   (* right arrow *)  'M' : if x1 < W then begin
  560.                              x1 := x1 +1 ;
  561.                              gotoxy(col,row) ; write(NumStr) ;
  562.                              gotoxy(Col+x1-1,row) ;
  563.                              highlight(NumStr[x1]) ;
  564.                                           end ;
  565.                      'H' : goto Bend ;
  566.                      'P' : goto Bend ;
  567.                      F1  : begin color(15,0) ; clrscr ; halt ; end ;
  568.                    end ;
  569.                                     end
  570.                       Else Jump := '^' ;
  571.                                   end
  572.  
  573.            Else if Ch<>chr(13) then Beep ;
  574.  
  575.      Until (Ch=chr(13)) or (Jump='^') ;
  576.  
  577.    Bend : if NumStr <> '' then
  578.           begin
  579.                while Pos(' ',NumStr)<>0 do          { Delete all spaces }
  580.                  delete(NumStr,Pos(' ',NumStr),1) ;
  581.                if NumStr[1]='.' then NumStr := '0'+NumStr ;
  582.                color(11,0) ;
  583.                gotoxy(col,row) ; write(copy(NumStr+space,1,w)) ;
  584.                val(NumStr,Num,code) ;
  585.           end ;
  586.  
  587.     until code=0 ;
  588.    end ;
  589.  
  590. {----------------------- Line Routines --------------------------------------}
  591.  
  592. Procedure LinePoints(X1,Y1,X2,Y2 : integer ) ;
  593.     Var
  594.        x,x3,y,y3,z,a,b,dx,dy,d,deltap,deltag : integer ;
  595.  
  596.    Procedure PackArray(X,Y : integer ) ;
  597.     Const
  598.          Bits : array[0..7] of byte = (1,2,4,8,16,32,64,128) ;
  599.     Var
  600.        Bit , XInx : Byte ;
  601.     begin
  602.       if ((X>1) and (X<640)) and ((Y<398) and (Y>2)) then
  603.       begin
  604.          XInx := X shr 3 ;
  605.          Bit := x -(XInx shl 3) ;
  606.        PrintByte^[y,XInx] := PrintByte^[y,XInx] or Bits[Bit] ;
  607.       end ;
  608.     end ;
  609.  
  610.    Function TestY(x,y: integer) : Boolean ;
  611.        begin
  612.          if (X>1) and (X<640) then begin
  613.             TestY:=False ;
  614.             if y<=UpY[x] then TestY:=true ;
  615.             if y>=LoY[x] then TestY:=True ;
  616.                                    end
  617.          else TestY:=False ;
  618.        end ;
  619.  
  620.     begin
  621.       dx := abs(x2-x1) ;
  622.       dy := abs(y2-y1) ;
  623.  
  624.       if dy <= dx then
  625.          begin
  626.            x := x1 ; y := y1 ; z := x2 ;
  627.            if x1 <= x2 then a := 1 else a := -1 ;
  628.            if y1 <= y2 then b := 1 else b := -1 ;
  629.            deltap := dy + dy ;
  630.            d      := deltap - dx ;
  631.            deltag := d - dx ;
  632.  
  633.            if Not Hide then Packarray(x,y)
  634.               else if TestY(x,y) then Packarray(x,y) ;
  635.            while x <> z do begin
  636.               x := x + a ;
  637.               if d<0 then d := d + deltap
  638.                  else begin
  639.                         y := y + b ; d := d + deltag ;
  640.                       end ;
  641.               if Not Hide then Packarray(x,y)
  642.                  else if TestY(x,y) then Packarray(x,y) ;
  643.                            end ;
  644.          end
  645.  
  646.       else
  647.         begin
  648.           y := y1 ; x := x1 ; z := y2 ;
  649.           if y1 <= y2 then a := 1 else a := -1 ;
  650.           if x1 <= x2 then b := 1 else b := -1 ;
  651.           deltap := dx + dx ;
  652.           d      := deltap - dy ;
  653.           deltag := d - dy ;
  654.           if Not Hide then Packarray(x,y)
  655.              else if TestY(x,y) then Packarray(x,y) ;
  656.           while y <> z do begin
  657.                 y := y + a ;
  658.                 if d<0 then d := d + deltap
  659.                    else begin
  660.                           x := x + b ; d := d + deltag ;
  661.                         end ;
  662.                 if Not Hide then Packarray(x,y)
  663.                    else if TestY(x,y) then Packarray(x,y) ;
  664.                           end ;
  665.        end ;
  666.     end ;    { Pixel_Line }
  667.  
  668. Procedure SetUpLoY(X1,Y1,X2,Y2 : integer ) ;
  669.     Var
  670.        x,x3,y,y3,z,a,b,dx,dy,d,deltap,deltag : integer ;
  671.  
  672.    Procedure SetUpLo(x,y : Integer) ;
  673.        begin
  674.          if (X>1) and (X<640) then begin
  675.               if y<UpY[x] then begin
  676.                  if y>1 then UpY[x]:=y
  677.                     else UpY[x]:=1 ;
  678.                                end ;
  679.               if y>LoY[x] then begin
  680.                  if y<399 then LoY[x]:=y
  681.                     else LoY[x]:=399 ;
  682.                                end ;
  683.                                    end ;
  684.        end ;
  685.  
  686.     begin
  687.       dx := abs(x2-x1) ;
  688.       dy := abs(y2-y1) ;
  689.  
  690.       if dy <= dx then
  691.          begin
  692.            x := x1 ; y := y1 ; z := x2 ;
  693.            if x1 <= x2 then a := 1 else a := -1 ;
  694.            if y1 <= y2 then b := 1 else b := -1 ;
  695.            deltap := dy + dy ;
  696.            d      := deltap - dx ;
  697.            deltag := d - dx ;
  698.            SetUpLo(x,y) ;
  699.            while x <> z do begin
  700.               x := x + a ;
  701.               if d<0 then d := d + deltap
  702.                  else begin
  703.                         y := y + b ; d := d + deltag ;
  704.                       end ;
  705.               SetUpLo(x,y) ;
  706.                            end ;
  707.          end
  708.  
  709.       else
  710.         begin
  711.           y := y1 ; x := x1 ; z := y2 ;
  712.           if y1 <= y2 then a := 1 else a := -1 ;
  713.           if x1 <= x2 then b := 1 else b := -1 ;
  714.           deltap := dx + dx ;
  715.           d      := deltap - dy ;
  716.           deltag := d - dy ;
  717.           SetUpLo(x,y) ;
  718.           while y <> z do begin
  719.                 y := y + a ;
  720.                 if d<0 then d := d + deltap
  721.                    else begin
  722.                           x := x + b ; d := d + deltag ;
  723.                         end ;
  724.                 SetUpLo(x,y) ;
  725.                           end ;
  726.        end ;
  727.     end ;    { Pixel_Line }
  728.  
  729.  
  730. {---------------------------- Screen Line Routines -----------------------}
  731.  
  732. Procedure LinePointsS(X1,Y1,X2,Y2 : integer ) ;
  733.     Var
  734.        x,x3,y,y3,z,a,b,dx,dy,d,deltap,deltag : integer ;
  735.  
  736.    Procedure PackArrayS(X,Y : integer ) ;
  737.     Const
  738.          Bits : array[0..7] of byte = (128,64,32,16,8,4,2,1) ;
  739.     Var
  740.        Bit , XInx : Byte ;
  741.        Ye : integer ;
  742.     begin
  743.       if ((X>128) and (X<639)) and ((Y<199) and (Y>10)) then
  744.         begin
  745.          XInx := X shr 3 ;
  746.          Bit := x -(XInx shl 3) ;
  747.          Ye := y shr 1 ;
  748.          if y mod 2 = 0 then
  749.             EV[ye,XInx] := EV[ye,XInx] or Bits[Bit]
  750.            else OV[ye,XInx] := OV[ye,XInx] or Bits[Bit] ;
  751.         end ;
  752.     end ;
  753.  
  754.    Function TestY(x,y : Integer) : Boolean ;
  755.        begin
  756.          if (X>1) and (X<640) then begin
  757.               TestY:=False ;
  758.               if y<=UpSY[x] then TestY:=true ;
  759.               if y>=LoSY[x] then TestY:=True ;
  760.                                    end
  761.          else TestY := False ;
  762.        end ;
  763.  
  764.     begin
  765.       dx := abs(x2-x1) ;
  766.       dy := abs(y2-y1) ;
  767.  
  768.       if dy <= dx then
  769.          begin
  770.            x := x1 ; y := y1 ; z := x2 ;
  771.            if x1 <= x2 then a := 1 else a := -1 ;
  772.            if y1 <= y2 then b := 1 else b := -1 ;
  773.            deltap := dy + dy ;
  774.            d      := deltap - dx ;
  775.            deltag := d - dx ;
  776.  
  777.            if Not Hide then PackarrayS(x,y)
  778.               else if TestY(x,y) then PackarrayS(x,y) ;
  779.  
  780.            while x <> z do begin
  781.               x := x + a ;
  782.               if d<0 then d := d + deltap
  783.                  else begin
  784.                         y := y + b ; d := d + deltag ;
  785.                       end ;
  786.               if Not Hide then PackarrayS(x,y)
  787.                  else if TestY(x,y) then PackarrayS(x,y) ;
  788.                            end ;
  789.          end
  790.  
  791.       else
  792.         begin
  793.           y := y1 ; x := x1 ; z := y2 ;
  794.           if y1 <= y2 then a := 1 else a := -1 ;
  795.           if x1 <= x2 then b := 1 else b := -1 ;
  796.           deltap := dx + dx ;
  797.           d      := deltap - dy ;
  798.           deltag := d - dy ;
  799.           if Not Hide then PackarrayS(x,y)
  800.              else if TestY(x,y) then PackarrayS(x,y) ;
  801.           while y <> z do begin
  802.                 y := y + a ;
  803.                 if d<0 then d := d + deltap
  804.                    else begin
  805.                           x := x + b ; d := d + deltag ;
  806.                         end ;
  807.  
  808.                 if Not Hide then PackarrayS(x,y)
  809.                    else if TestY(x,y) then PackarrayS(x,y) ;
  810.                           end ;
  811.        end ;
  812.     end ;    { Pixel_Line }
  813.  
  814. Procedure SetUpLoYS(X1,Y1,X2,Y2 : integer ) ;
  815.     Var
  816.        x,x3,y,y3,z,a,b,dx,dy,d,deltap,deltag : integer ;
  817.  
  818.  
  819.    Procedure SetUpLo(x,y : Integer) ;
  820.        begin
  821.          if (X>1) and (X<640) then begin
  822.               if y<UpSY[x] then begin
  823.                  if y>1 then UpSY[x]:=y
  824.                     else UpSY[x]:=1 ;
  825.                                 end ;
  826.               if y>LoSY[x] then begin
  827.                  if y<199 then LoSY[x]:=y
  828.                     else LoSY[x]:=199 ;
  829.                                 end ;
  830.                                    end ;
  831.        end ;
  832.  
  833.     begin
  834.       dx := abs(x2-x1) ;
  835.       dy := abs(y2-y1) ;
  836.  
  837.       if dy <= dx then
  838.          begin
  839.            x := x1 ; y := y1 ; z := x2 ;
  840.            if x1 <= x2 then a := 1 else a := -1 ;
  841.            if y1 <= y2 then b := 1 else b := -1 ;
  842.            deltap := dy + dy ;
  843.            d      := deltap - dx ;
  844.            deltag := d - dx ;
  845.  
  846.            SetUpLo(x,y) ;
  847.  
  848.            while x <> z do begin
  849.               x := x + a ;
  850.               if d<0 then d := d + deltap
  851.                  else begin
  852.                         y := y + b ; d := d + deltag ;
  853.                       end ;
  854.               SetUpLo(x,y) ;
  855.                            end ;
  856.          end
  857.  
  858.       else
  859.         begin
  860.           y := y1 ; x := x1 ; z := y2 ;
  861.           if y1 <= y2 then a := 1 else a := -1 ;
  862.           if x1 <= x2 then b := 1 else b := -1 ;
  863.           deltap := dx + dx ;
  864.           d      := deltap - dy ;
  865.           deltag := d - dy ;
  866.           SetUpLo(x,y) ;
  867.           while y <> z do begin
  868.                 y := y + a ;
  869.                 if d<0 then d := d + deltap
  870.                    else begin
  871.                           x := x + b ; d := d + deltag ;
  872.                         end ;
  873.                 SetUpLo(x,y) ;
  874.                           end ;
  875.        end ;
  876.     end ;    { Pixel_Line }
  877.  
  878. {------------------------ Printer Routines ----------------------------------}
  879.  
  880. Procedure QuitPrint ;
  881.           begin
  882.                gotoxy(2,15) ; write('Stop Print (Y/N) ?') ;
  883.                               read(kbd,ch) ;
  884.                if Upcase(ch) = 'Y' then begin
  885.                                              Halt ;
  886.                                         end ;
  887.           end ;
  888.  
  889. Procedure LowResPrinter ;
  890.           var
  891.              x , y : integer ;
  892.           begin
  893.              write(lst,^[,'@',^[,'A',chr(8)) ;
  894.              for X := 79 downto 0 do
  895.              begin
  896.                write(lst,^[,'K',chr(144),chr(1)) ;
  897.                for y := 1 to 400 do
  898.                    write(lst,chr(PrintByte^[y,x])) ;
  899.                writeln(lst) ;
  900.                if keypressed then QuitPrint ;
  901.              end ;
  902.              writeln(lst) ;
  903.           end ;
  904.  
  905. Procedure DoubleWidePrint ;
  906.           var
  907.              X , Y , Y1 , a , b : integer ;
  908.              DoubleByte : array[1..2,1..240] of Byte ;
  909.  
  910.    Procedure TestBits(Bit ,TestByte : byte ; var Present : Boolean) ;
  911.      const
  912.           Bits : array[1..8] of byte = (254,253,251,247,239,223,191,127) ;
  913.        var
  914.           Test : byte ;
  915.      begin
  916.           Test := TestByte or Bits[Bit] ;
  917.           if Test = 255 then Present := true
  918.              Else Present := False ;
  919.      end ;
  920.  
  921.    Procedure GetDoubleBytes(X , C : byte) ;
  922.           Const
  923.                Tits : array[1..8] of byte = (3,12,48,192,3,12,48,192) ;
  924.           var
  925.              y : integer ;
  926.              a , b , tit : byte ;
  927.              Present : Boolean ;
  928.           begin
  929.                for  b := 1 to Y1 do
  930.                     begin
  931.                          for Tit := 8 downto 5 do
  932.                              begin
  933.                                   TestBits(tit,PrintByte^[b+c,x],Present) ;
  934.                                   if Present then DoubleByte[1,b] :=
  935.                                      DoubleByte[1,b] or Tits[tit] ;
  936.                                   TestBits(tit-4,PrintByte^[b+c,x],present) ;
  937.                                   if present then DoubleByte[2,b] :=
  938.                                      DoubleByte[2,b] or Tits[tit-4] ;
  939.                              end ;
  940.                     end ;
  941.           end ;
  942.  
  943.    begin
  944.         b := 0 ; Y1:=240 ;
  945.         for a := 1 to 2 do
  946.           begin
  947.             if a=2 then begin
  948.                           b:=240 ;
  949.                           Y1:=MaxY-240 ;
  950.                         end ;
  951.  
  952.             write(lst,^[,'@',^[,'A',chr(8)) ;
  953.             for X := 79 downto 0 do
  954.              begin
  955.                fillchar(DoubleByte,sizeof(DoubleByte),0) ;
  956.                GetDoubleBytes(x,b) ;
  957.  
  958.                write(lst,^[,'K',chr((2*Y1)-256),chr(1)) ;
  959.                for y := 1 to Y1 do
  960.                    write(lst,chr(DoubleByte[1,Y]),chr(DoubleByte[1,Y])) ;
  961.                    if Y1<240 then writeln(lst) ;
  962.  
  963.                write(lst,^[,'K',chr((2*Y1)-256),chr(1)) ;
  964.                for y := 1 to Y1 do
  965.                    write(lst,chr(DoubleByte[2,Y]),chr(DoubleByte[2,Y])) ;
  966.                    if Y1<240 then writeln(lst) ;
  967.  
  968.                if keypressed then QuitPrint ;
  969.              end ;
  970.             write(lst,chr(10),chr(10),chr(10),chr(10)) ;
  971.           end ;
  972.    end ;
  973.  
  974. Procedure PrintStats ;
  975.     begin
  976.          write(lst,#27+#48) ;
  977.          writeln(lst,'Equation: ',equation) ;
  978.         WRITE(lst,'YRot: ',Theta:4:1) ;
  979.         WRITE(lst,'  XRot: ',Phi:4:1) ;
  980.         WRITE(lst,'  Obj : ',Object:3:0) ;
  981.         WRITEln(lst,'  Im : ',Image:4:0) ;
  982.         write(lst,'  XRan: ',HighX:2:0) ;
  983.         write(lst,'  YRan: ',HighY:2:0) ;
  984.         WRITE(lst,'  XInc: ',XIncrement:3:2) ;
  985.         WRITE(lst,'  YInc: ',YIncrement:3:2) ;
  986.         write(lst,'   YTr : ',CenterY:3:0) ;
  987.         write(lst,'   XTr : ',CenterX:3:0) ;
  988.         write(lst,'  ScX : ',ScaleX:3:1) ;
  989.         write(lst,'  ScY : ',ScaleY:3:1) ;
  990.         writeln(lst,chr(12));
  991.     end ;
  992.  
  993. Procedure WhichPrintout ;
  994.     Var Ch : Char ;
  995.           begin
  996.                gotoxy(2,21) ; write('[S]mall or [L]arge') ;
  997.                               read(kbd,ch) ;
  998.                if Upcase(ch) = 'S' then LowResPrinter ;
  999.                if Upcase(ch) = 'L' then DoubleWidePrint ;
  1000.                if (Upcase(ch)='S') or (Upcase(ch)='L') then
  1001.                   PrintStats ;
  1002.           end ;
  1003. {----------------------------------------------------------------------------}
  1004.  
  1005. Procedure SetCoor ;
  1006.     Var
  1007.        XE,YE,ZE ,XX , YY , Fun : REAL;
  1008.        aX , aY : integer ;
  1009.     BEGIN
  1010.         XE:=-X*SinTheta+Y*CosTheta;
  1011.         YE:=-X*CTCP-Y*STCP+Z*SinPhi ;
  1012.         ZE:=-X*SPCT-Y*SPST-Z*CosPhi+OBJECT ;
  1013.  
  1014.         XX := CenterX + Im1*XE/ZE ;
  1015.         YY := CenterY - Im2*YE/ZE ;
  1016.  
  1017.                      CvPt^[C,P].x := Round(1.1*XX)+60 ;
  1018.                      ScCvPt^[C,P].x := Round(xx)+128 ;
  1019.  
  1020.                      CvPt^[C,P].y := Round(YY) shl 1 ;
  1021.                      ScCvPt^[C,P].y := Round(yy) ;
  1022.    END;
  1023.  
  1024. PROCEDURE GETSINCOS;
  1025.    BEGIN
  1026.         SinTheta := SIN(THETA) ;
  1027.         SinPhi   := SIN(PHI) ;
  1028.         CosTheta := COS(THETA) ;
  1029.         CosPhi   := COS(PHI);
  1030.         CTCP := CosTheta*CosPhi ;
  1031.         STCP := SinTheta*CosPhi ;
  1032.         SPCT := SinPhi*CosTheta ;
  1033.         SPST := SinPhi*SinTheta ;
  1034.    end ;
  1035.  
  1036. PROCEDURE GetInfo;
  1037.     Var x : integer ;
  1038.  
  1039.     BEGIN
  1040.       X := 1 ; color(11,0) ;
  1041.     repeat
  1042.       Case x of
  1043.      1:begin
  1044.                gotoxy(2,1) ; write('Z:=') ;
  1045.                input(5,1,75,[' '..'}'],#13,Equation,E) ;
  1046.        end ;
  1047.      2:begin   GOTOXY(2,4) ; WRITE('YRot: ') ;
  1048.                inputN(7,4,5,1,Theta,E) ;
  1049.        end ;
  1050.      3:begin   gotoxy(2,5) ; WRITE('XRot: ') ;
  1051.                inputN(7,5,5,1,Phi,E) ;
  1052.        end ;
  1053.      4:begin   gotoxy(2,6) ; WRITE('Obj : ') ;
  1054.                inputN(7,6,3,0,object,E) ;
  1055.        end ;
  1056.      5:begin   gotoxy(2,7) ; WRITE('Im  : ') ;
  1057.                inputN(7,7,4,0,image,E) ;
  1058.                Im1 := ScaleX*Image ; Im2 := ScaleY*Image ;
  1059.        end ;
  1060.      6:begin   gotoxy(2,9) ; write('XRan: ') ;
  1061.                inputN(7 ,9,2,0,HighX,E) ;
  1062.                           LowX := -HighX ;
  1063.        end ;
  1064.      7:begin   gotoxy(2,10) ; write('YRan: ') ;
  1065.                inputN(7 ,10,2,0,HighY,E) ;
  1066.                           LowY := -HighY ;
  1067.        end ;
  1068.      8:begin   gotoxy(2,11) ; WRITE('XInc: ') ;
  1069.                inputN(7 ,11,4,2,XIncrement,E) ;
  1070.        end ;
  1071.      9:begin   gotoxy(2,12) ; WRITE('YInc: ') ;
  1072.                inputN(7 ,12,4,2,YIncrement,E) ;
  1073.        end ;
  1074.     10:begin   gotoxy(2,13) ; WRITE('YTr : ') ;
  1075.                inputN(7 ,13,3,0,CenterY,E) ;
  1076.        end ;
  1077.     11:begin   gotoxy(2,14) ; write('XTr : ') ;
  1078.                inputN(7,14,3,0,CenterX,E) ;
  1079.        end ;
  1080.     12:begin   gotoxy(2,15) ; write('ScX : ') ;
  1081.                inputN(7,15,3,1,ScaleX,E) ;
  1082.                Im1 := ScaleX * Image ;
  1083.        end ;
  1084.     13:begin   gotoxy(2,16) ; write('ScY : ') ;
  1085.                inputN(7,16,3,1,ScaleY,E) ;
  1086.                Im2 := ScaleY * Image ;
  1087.        end ;
  1088.        end ; { case }
  1089.      if (E<>'H') then begin
  1090.                  if x<13 then x:=x+1
  1091.                   else x:= 1 ;
  1092.                       end
  1093.       else if x>1 then x:=x-1
  1094.               else x:=13 ;
  1095.  
  1096.     Until E='^' ;
  1097.  
  1098.                 END;
  1099.  
  1100. PROCEDURE PrintInfo;
  1101.  
  1102.     BEGIN
  1103.         gotoxy(2,1) ; write('Z:=',Equation) ;
  1104.         Gotoxy(2,4) ;  WRITE('YRot: ',Theta:4:1) ;
  1105.         gotoxy(2,5) ;  WRITE('XRot: ',Phi:4:1) ;
  1106.         gotoxy(2,6) ;  WRITE('Obj : ',Object:3:0) ;
  1107.         gotoxy(2,7) ;  WRITE('Im  : ',Image:4:0) ;
  1108.         gotoxy(2,9) ;  write('XRan: ',HighX:2:0) ;
  1109.         gotoxy(2,10) ; write('YRan: ',HighY:2:0) ;
  1110.         gotoxy(2,11) ; WRITE('XInc: ',XIncrement:3:2) ;
  1111.         gotoxy(2,12) ; WRITE('YInc: ',YIncrement:3:2) ;
  1112.         gotoxy(2,13) ; write('YTr : ',CenterY:3:0) ;
  1113.         gotoxy(2,14) ; write('XTr : ',CenterX:3:0) ;
  1114.         gotoxy(2,15) ; write('ScX : ',ScaleX:2:1) ;
  1115.         gotoxy(2,16) ; write('ScY : ',ScaleY:2:1) ;
  1116.  
  1117.     END;
  1118.  
  1119. Procedure ClearBitsArray ;
  1120.           var X , Y  : integer ;
  1121.           begin
  1122.                for X := 0 to 79 do
  1123.                    begin
  1124.                         PrintByte^[1,x]   := 255 ;
  1125.                         PrintByte^[2,x]   := 255 ;
  1126.                         PrintByte^[3,x]   := 255 ;
  1127.                         PrintByte^[398,x] := 255 ;
  1128.                         PrintByte^[399,x] := 255 ;
  1129.                         PrintByte^[400,x] := 255 ;
  1130.                    end ;
  1131.                for Y := 4 to 397 do
  1132.                    begin
  1133.                         PrintByte^[y,0]  := PrintByte^[y,0] or 7 ;
  1134.                         PrintByte^[y,79] := PrintByte^[y,79] or 224 ;
  1135.                    end ;
  1136.           end ;
  1137.  
  1138. Procedure BoxIn(x,y,x1,y1:integer) ;
  1139.           begin
  1140.                draw(x,y,x1,y,11) ;
  1141.                draw(x,y,x,y1,11) ;
  1142.                draw(x,y1,x1,y1,11) ;
  1143.                draw(x1,y,x1,y1,11) ;
  1144.           end ;
  1145.  
  1146. Procedure graphicInitialize ;
  1147.           begin
  1148.                HiRes ; HiResColor(11) ;
  1149.                PrintInfo ;
  1150.                boxin(128,10,639,199) ;
  1151.  
  1152.           end ;
  1153.  
  1154. Procedure Center(phrase : str80 ; row : integer) ;
  1155.     Const Blank = '                                                          ' ;
  1156.  
  1157.     Var
  1158.       L , SL : integer ;
  1159.  
  1160.     begin
  1161.       L := Length(phrase) ;
  1162.       SL := (80-L) div 2 ;
  1163.       gotoxy(1,row) ;
  1164.       clreol ;
  1165.       write(copy(blank,1,SL),Phrase) ;
  1166.     end ;
  1167.  
  1168. Procedure Title ;
  1169.     begin
  1170.       clrscr ;
  1171.       Center(' 3D Graph ',10) ;
  1172.       center('With printer support for Epson',11) ;
  1173.       Center(' by Joe Martin ',12) ;
  1174.       Center('8/86',13) ;
  1175.       Center(' Ft. Walton Bch. FL ',14) ;
  1176.       center(' 1-904-862-7108 ',15) ;
  1177.       center(' any key to continue ',25) ;
  1178.       repeat until keypressed ;
  1179.     end ;
  1180.  
  1181. BEGIN  { MAIN PROGRAM }
  1182.     clrscr ;
  1183.     Equation := '2*COS(0.1*(X^2+Y^2))' ;
  1184.     Im1 := ScaleX*Image ; Im2 := ScaleY*Image ;
  1185.     Title ;
  1186.     clrscr ;
  1187.  
  1188. Start :
  1189.     Center('ESC - Start Graph     CR or Arrows for menu '+
  1190.                 '    F1 - Exit', 24) ;
  1191.     Ptime := 0.0 ;
  1192.     GetInfo ;
  1193.     graphicinitialize ;
  1194.     X:=LowX ;
  1195.     GetSinCos;
  1196.     New(ScCvPt) ;
  1197.     FillChar(ScCvPt^,SizeOf(ScCvPt^),0) ;
  1198.     New(CvPt) ;
  1199.     FillChar(CvPt^,SizeOf(CvPt^),0) ;
  1200.     New(PrintByte) ;
  1201.     FillChar(PrintByte^,SizeOf(PrintByte^),0) ;
  1202.  
  1203.  
  1204.     Parse(form,equation,N,Position) ;
  1205.     Zero := XIncrement*0.75 ;
  1206.     C := 1 ;
  1207.  
  1208.   Hide := False ;
  1209.   Ptime := timer ;
  1210.   NumCurves := Trunc((HighX-LowX)/XIncrement)+1 ;
  1211.   while X <= HighX do
  1212.   begin
  1213.        gotoxy(2,25) ; write(C:2,' ',NumCurves-c:3) ;
  1214.        Y := LowY ; P := 1 ;
  1215.        Z := Eval(N) ; SetCoor ; P := 2 ; Y := Y + YIncrement ;
  1216.  
  1217.        while Y <= HighY do
  1218.          begin
  1219.               Z := Eval(N) ;
  1220.               SetCoor ;
  1221.  
  1222.                  LinePointsS(ScCvPt^[c,p].x ,
  1223.                      ScCvPt^[c,p].y , ScCvPt^[c,p-1].x , ScCvPt^[c,p-1].y) ;
  1224.                  LinePoints(CvPt^[c,p].x ,
  1225.                      CvPt^[c,p].y , CvPt^[c,p-1].x , CvPt^[c,p-1].y) ;
  1226.  
  1227.               P := P + 1 ;
  1228.               Y := Y + YIncrement ;
  1229.          end ;
  1230.        C := C + 1 ;
  1231.        if keypressed then goto Cross ;
  1232.  
  1233.        X := X + XIncrement ;
  1234.   end ;
  1235.  
  1236. Cross :
  1237. gotoxy(24,2) ; write(timer:3:2) ; Ptime := 0.0 ;
  1238. NumCurves := C-1 ;
  1239. Numpoints := Trunc((HighY-LowY)/YIncrement)+1 ;
  1240.  
  1241.   gotoxy(2,20) ; write('Hidden(Y/N): ') ; read(kbd,Ch) ;
  1242.   if Upcase(Ch) <> 'Y' then goto Finish ;
  1243.  
  1244. Ptime := Timer ;
  1245.   graphicinitialize ;
  1246.  
  1247.   for a := 1 to 640 do
  1248.    begin
  1249.      UpSY[a]:= 199 ;
  1250.      LoSY[a]:= 1 ;
  1251.      UpY[a] := 399 ;
  1252.      LoY[a] := 1 ;
  1253.    end ;
  1254.  
  1255.   Hide := True ;
  1256.   FillChar(PrintByte^,SizeOf(PrintByte^),0) ;
  1257.   a := 0 ;
  1258.   for C := NumCurves downto 1 do
  1259.     begin
  1260.     First:=False ;
  1261.     a := a + 1 ; if a=1 then First:=True ;
  1262.  
  1263.       for P := 1 to NumPoints-1 do
  1264.         begin
  1265.  
  1266.           LinePointsS(ScCvPt^[c,p].x ,
  1267.                      ScCvPt^[c,p].y , ScCvPt^[c,p+1].x , ScCvPt^[c,p+1].y) ;
  1268.           LinePoints(CvPt^[c,p].x ,
  1269.                      CvPt^[c,p].y , CvPt^[c,p+1].x , CvPt^[c,p+1].y) ;
  1270.  
  1271.  
  1272.         end ;
  1273.  
  1274.     if C>1 then begin
  1275.       LinePointsS(ScCvPt^[c,p+1].x ,
  1276.                      ScCvPt^[c,p+1].y , ScCvPt^[c-1,p+1].x , ScCvPt^[c-1,p+1].y) ;
  1277.       LinePoints(CvPt^[c,p+1].x ,
  1278.                      CvPt^[c,p+1].y , CvPt^[c-1,p+1].x , CvPt^[c-1,p+1].y) ;
  1279.       LinePointsS(ScCvPt^[c,1].x ,
  1280.                      ScCvPt^[c,1].y , ScCvPt^[c-1,1].x , ScCvPt^[c-1,1].y) ;
  1281.       LinePoints(CvPt^[c,1].x ,
  1282.                      CvPt^[c,1].y , CvPt^[c-1,1].x , CvPt^[c-1,1].y) ;
  1283.                 end ;
  1284.  
  1285.       for P := 1 to NumPoints-1 do
  1286.         begin
  1287.           SetUpLoYS(ScCvPt^[c,p].x ,
  1288.                     ScCvPt^[c,p].y , ScCvPt^[c,p+1].x , ScCvPt^[c,p+1].y) ;
  1289.           SetUpLoY(CvPt^[c,p].x ,
  1290.                    CvPt^[c,p].y , CvPt^[c,p+1].x , CvPt^[c,p+1].y) ;
  1291.         end ;
  1292.  
  1293.    if C>1 then begin
  1294.      SetUpLoYS(ScCvPt^[c,p+1].x ,
  1295.                      ScCvPt^[c,p+1].y , ScCvPt^[c-1,p+1].x , ScCvPt^[c-1,p+1].y) ;
  1296.      SetUpLoY(CvPt^[c,p+1].x ,
  1297.                      CvPt^[c,p+1].y , CvPt^[c-1,p+1].x , CvPt^[c-1,p+1].y) ;
  1298.      SetUpLoYS(ScCvPt^[c,1].x ,
  1299.                      ScCvPt^[c,1].y , ScCvPt^[c-1,1].x , ScCvPt^[c-1,1].y) ;
  1300.      SetUpLoY(CvPt^[c,1].x ,
  1301.                      CvPt^[c,1].y , CvPt^[c-1,1].x , CvPt^[c-1,1].y) ;
  1302.                end ;
  1303.    if keypressed then goto finish ;
  1304.     end ;
  1305.   Finish :
  1306.  
  1307.   ClearBitsArray ;
  1308.  
  1309.   GotoXY(1,19) ; write(' DONE ') ;
  1310.   gotoxy(24,2) ; write(timer:3:2) ;
  1311.   repeat
  1312.   gotoxy(2,20) ; writeln('Printout (Y/N)') ;
  1313.   Read(kbd,ch) ;
  1314.   if Upcase(ch) = 'Y' then WhichPrintout ;
  1315.   until Upcase(Ch) <> 'Y' ;
  1316.   Dispose(PrintByte) ;
  1317.   Dispose(ScCvPt) ;
  1318.   Dispose(CvPt) ;
  1319.   Dispose(N) ;
  1320.   gotoxy(2,21) ; write('Any key To Cont.') ;
  1321.  
  1322. REPEAT UNTIL KEYPRESSED ;
  1323. TextMode ; goto start ;
  1324.  END.  { END PROGRAM }
  1325.